<?php
/**
 * Created by PhpStorm.
 * User: eugene
 * Date: 2018/3/12
 * Time: 18:14
 */

namespace App\Repos;


use App\Models\Car;
use App\Models\Member;
use App\Models\MyCar;
use App\Models\MyStage;
use App\Models\Parking;
use App\Models\Record;
use App\Traits\Stage;
use App\Transformers\CarTransformer;
use App\Transformers\StageTransformer;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Request;

/**
 * 车辆状态提供器
 *
 * Class CarRepo
 * @package App\Repos
 */
class CarRepo
{
    use Stage;
    public
        $status, //车辆状态码
        $attr, //车辆附加状态属性
        $status_text,//车辆状态描述
        $predict_income,//车辆预期收入
        $current_income,//车辆当前已产生收入
        $parking_end_time,//车辆停车满时间
        $record,//车位记录
        $max_stop_time,
        $tempParking,
        $parking;//预要停入的车位或已停入的车位
    public $forfeit=0;//车辆罚金（如果有的话）
    
    protected $punished_persent,$CarCredit;//道具效果
    

    
    public function setTempParking($parking)
    {
        $this->tempParking = $parking;
        return $this;
    }
    
    
    /**
     * a)  1  如果车辆在好友车位中正常停靠且在收益期中则并显示收益期结束的时间，如"收益期到16:48结束"
     * b)  2  如果收益期已经结束则显示"收益期已结束"
     * c)  3  如果在好友车位中被贴条则显示"被车友贴条啦"
     * d)  4  如果车辆没有停靠在别人车位中且持续时间不超过1小时，则显示"正处于保护期"
     * e)  5  如果车辆超过1小时没有停靠在别人车位则显示"违停"及持续的时间，如"已违停X分钟"
     *
     * @param \App\Models\MyCar $myCar
     */
    public function countStatus(MyCar $myCar)
    {
        $user = Member::find($myCar->uid);
        $car = Car::find($myCar->CarID);
        //声明所有初始状态
        $config_car = config('car.cfgStopLimit');
        $this->max_stop_time = $config_car['maxStopTime'];
        $this->punished_persent = $config_car['PunishedPersent'];
        $this->CarCredit = $car->CarCredit;
        $this->forfeit = 0;
        $this->status = 0;
        $this->attr=null;
        $this->status_text = '';
        $this->predict_income = 0;
        $this->current_income = 0;
        $this->parking_end_time = 0;
        $this->record=null;
        $this->parking=null;
        //道具校正
        if($user && $car){
            $stages = MyStage::where('car_id',$myCar->ID)->where('uid',$myCar->uid)->get();
            if($stages){
                foreach ($stages as $stage) {
                    $stage_type = $stage->stage->StageType;
                    if($stage_type == 1){
                        $this->stage1();
                    }
                    if($stage_type == 3){
                        $this->stage3();
                    }
                    if($stage_type == 4){
                        $this->stage4();
                    }
                }
                
            }
        }
        
        $record = Record::withoutGlobalScope('status')->where('ParkUid',$user->id)->where('CarID',$car->id)->where('myCarID',$myCar->ID)->first();
        $my_car_log = MyCar::where('uid',$user->id)->where('ID',$myCar->ID)->firstOrFail();
    
        $parking=null;
        
        if($this->tempParking){
            $parking = $this->tempParking;
        }elseif($record){
            $this->parking = $parking = Parking::find($record->Parklot);
        }
    
        if($parking){
            if($parking->isFree()){
                $percent = config('car.cfgStopLimit.ParkingFreePersent',1);
                $this->CarCredit*=$percent;
            }elseif($parking->isPrivate()){
                $percent = config('car.cfgStopLimit.ParkingPrivatePersent',1.1);
                $this->CarCredit*=$percent;
            }elseif($parking->isNewEnergy()){
                //新能源校正
                $percent = config('car.cfgStopLimit.ParkingChargePersent',1.2);
                $this->CarCredit*=$percent;
                
                if($car->isNewEnergy()){
                    $percent = config('car.cfgStopLimit.ParkingChargeCarPersent',1.1);
                    $this->CarCredit*=$percent;
                }
            }
            $this->predict_income = $this->CarCredit * $this->max_stop_time;
        }
        
        if($record){
            $this->record = $record;
            
            $this->parking_end_time = Carbon::parse($record->ParkStartTime)->addMinutes($this->max_stop_time);
            
            //被贴条赶走，或开走的保护期或违停
            if($record->ParkStatus == 0){
                $this->anotherStatus($record->ParkStartTime);
                return;
            }
            
            $stop_min = Carbon::now()->diffInMinutes(Carbon::parse($record->ParkStartTime));
            $diff_min = $stop_min - $this->max_stop_time;
            //如果停车时间超过了最大停车时间
            if($diff_min > 0){
                //正常停车时的保护期或违停
                $this->status = 2;
                $this->status_text = '收益期已结束';
                
                if($parking){
                    $this->current_income = $this->predict_income;
                }
            }else{
                //还在收益期内
                $this->status = 1;
                $this->attr = -$diff_min;
                $this->status_text = '收益期到'.Carbon::now()->addMinutes(-$diff_min)->format('H:i').'结束';
                //收益期内可以
                if($parking){
                    $this->current_income = $this->CarCredit * $stop_min;
                }
            }
            //收益期被贴条
            if($record->ParkPunish == 1){
                $this->status = 3;
                $this->status_text .= '(被车友贴条啦)';
                $this->predict_income*=$this->punished_persent;
                
                if($parking){
                    $this->current_income = $this->CarCredit * $stop_min * $this->punished_persent;
                }
            }
    
            $this->predict_income = floor($this->predict_income);
            $this->current_income = floor($this->current_income);
            
        }else{
            //刚买车时的保护期或违停
            $this->anotherStatus($my_car_log->BuyTime);
        }
        
    }
    
    private function anotherStatus($last_park_time)
    {
        $invalid_min = Carbon::now()->diffInMinutes(Carbon::parse($last_park_time)) - config('car.cfgStopLimit.maxProtectTime');
        
        if($invalid_min > 0){
            $this->status = 5;
            $this->attr = $invalid_min;
            $this->status_text = '已违停'.Carbon::now()->addMinutes($invalid_min)->diffForHumans(null,true);
            $this->forfeit = min($invalid_min,config('car.cfgStopLimit.maxDriveTime')) * config('car.cfgStopLimit.DriveCredit');
            //$this->predict_income-=$this->forfeit;
        }else{
            $this->status = 4;
            $this->attr = -$invalid_min;
            $this->status_text = '正处于保护期,还有'.-$invalid_min.'分钟结束';
        }
        $this->predict_income = floor($this->predict_income);
        $this->current_income = floor($this->current_income);
    }
    
    
    public function myCars($user)
    {
        $user_car_limit = $user->getCarLimit();
        
        $levels = config('car.levels');
    
        $my_cars = MyCar::where('uid',$user->id)->orderByDesc('id')->with('car')->get();
        if($my_cars){
            $list = $my_cars->transform(function($item)use($user){
                $stage = MyStage::where('uid',$user->id)->where('car_id',$item->ID)->with('stage')->get();
                $items=null;
                if($stage){
                    $items = $stage->transform(function($item){
                        return (new StageTransformer())->singleData($item->stage);
                    });
                }
                $this->countStatus($item);
                $normal_items = [];
                $parked_index = 0;
                if($this->parking && $this->record && $this->status <= 3){
                    $parked_index = ParkingRepo::countParkIndex($this->record->ParkWhoUid,$this->parking->id);
                    $normal_items = $items;
                }
                $attr = [
                    'status'=>$this->status,
                    'status_text'=>$this->status_text,
                    'forfeit'=>$this->forfeit ? :0,
                    'current_income'=> $this->current_income,
                    'predict_income'=> $this->predict_income,
                    'parking_end_hour'=>round($this->max_stop_time/60),
                    'parked'=>$this->status <= 3 ? $this->record->ParkWhoUid : 0,
                    'parked_index'=>$parked_index,
                    'empty_car_position'=>0,//标识非空车辆位置
                    'items'=>$normal_items,
                    'id'=>$item->ID,
                ];
        
                return array_merge((new CarTransformer())->singleData($item->car),$attr);
            });
        }
        
        $can_buy_cars = $user_car_limit - \count($my_cars);
        if($can_buy_cars > 0){
            for($i=0;$i<$can_buy_cars;$i++){
                $list[]=[
                    'empty_car_position'=>2,//标识已购车位
                ];
            }
            
        }
        //将空车辆位置格式化
        $empty_car_positions = \array_slice($levels,$user_car_limit,null,true);
        
        if(\is_array($empty_car_positions)){
            foreach ($empty_car_positions as $key=>$empty_car) {
                $list[]=[
                    'empty_car_position'=>1,//标识未购车位
                    'level'=>$key,
                    'car_limit'=>$empty_car['car_limit'],
                    'need_gold'=>$empty_car['gold'],
                ];
            }
        }
        
        return $list;
    }
    
    
    public static function getMyCarId($user_id,$car_id)
    {
        return MyCar::where('uid',$user_id)->where('CarID',$car_id)->value('ID');
    }
    
    
    
        
    

    
}